package main

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/bilibili/discovery/conf"
	"github.com/bilibili/discovery/discovery"
	"github.com/bilibili/discovery/model"
	"github.com/bilibili/discovery/naming"
	pb "go_knowledge/micro-service/consignment/service/proto/consignment"
	"io/ioutil"
)

const (
	ADDRESS           = "localhost:50051"
	DEFAULT_INFO_FILE = "micro-service/consignment/client/consignment.json"
)

// 读取 consignment.json 中记录的货物信息
func parseFile(fileName string) (*pb.Consignment, error) {
	data, err := ioutil.ReadFile(fileName)
	if err != nil {
		return nil, err
	}
	var consignment *pb.Consignment
	err = json.Unmarshal(data, &consignment)
	if err != nil {
		return nil, errors.New("consignment.json file content error")
	}
	return consignment, nil
}

func main() {
	dis, c := discovery.New(&conf.Config{
		Nodes: []string{"127.0.0.1:7171"},
	})
	defer c()
	in, err := dis.Fetch(context.Background(), &model.ArgFetch{
		Zone:   "sh1",
		Env:    "test",
		AppID:  "provider",
		Status: 1,
	})
	if err != nil {
		panic(err)
	}
	fmt.Printf("%v", in)

	//// 连接到 gRPC 服务器
	//conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure())
	//if err != nil {
	//	log.Fatalf("connect error: %v", err)
	//}
	//defer conn.Close()
	//
	//// 初始化 gRPC 客户端
	//client := pb.NewShippingServiceClient(conn)
	//
	//// 在命令行中指定新的货物信息 json 文件
	//infoFile := DEFAULT_INFO_FILE
	//if len(os.Args) > 1 {
	//	infoFile = os.Args[1]
	//}
	//
	//// 解析货物信息
	//consignment, err := parseFile(infoFile)
	//if err != nil {
	//	log.Fatalf("parse info file error: %v", err)
	//}
	//
	//// 调用 RPC
	//// 将货物存储到我们自己的仓库里
	//resp, err := client.CreateConsignment(context.Background(), consignment)
	//if err != nil {
	//	log.Fatalf("create consignment error: %v", err)
	//}
	//
	//// 新货物是否托运成功
	//log.Printf("created: %t", resp.Created)
	//
	//// 列出目前所有托运的货物
	//resp, err = client.GetConsignments(context.Background(), &pb.GetRequest{})
	//if err != nil {
	//	log.Fatalf("failed to list consignments: %v", err)
	//}
	//for _, c := range resp.Consignments {
	//	log.Printf("%+v", c)
	//}
}

type consumer struct {
	conf  *naming.Config
	appID string
	dis   naming.Resolver
	ins   []*naming.Instance
}

func ExampleResolver_Watch() {
	conf := &naming.Config{
		Nodes:  []string{"127.0.0.1:7171"},
		Zone:   "sh1",
		Env:    "test",
		Region: "",
	}
	dis := naming.New(conf)
	c := &consumer{
		conf:  conf,
		appID: "provider",
		dis:   dis.Build("provider"),
	}
	rsl := dis.Build(c.appID)
	ins, _ := rsl.Fetch()
	fmt.Printf("%v,,,,,,,,,", ins.Instances["sh001"][0])
	//ch := rsl.Watch()
	//c.getInstances(ch)
	//in := c.getInstance()
	//fmt.Println(in)
	//_ = in
}

func (c *consumer) getInstances(ch <-chan struct{}) {
	for { // NOTE: 通过watch返回的event chan =>
		if _, ok := <-ch; !ok {
			return
		}
		// NOTE: <= 实时fetch最新的instance实例
		ins, ok := c.dis.Fetch()
		if !ok {
			continue
		}
		// get local zone instances, otherwise get all zone instances.
		if in, ok := ins.Instances[c.conf.Zone]; ok {
			c.ins = in
		} else {
			for _, in := range ins.Instances {
				c.ins = append(c.ins, in...)
			}
		}
		return
	}
}
func (c *consumer) getInstance() (ins *naming.Instance) {
	// get instance by loadbalance
	// you can use any loadbalance algorithm what you want.
	if len(c.ins) == 0 {
		return nil
	}
	return c.ins[0]
}
